import { Dep } from "./Dep";

interface Data {
  [key: string]: any;
}

export class Observer {
  constructor(data: Data) {
    this.walk(data);
  }
  private walk(data: Data) {
    if (!data || typeof data !== "object") return;
    Object.keys(data).forEach((key) =>
      this.definedReactive(data, key, data[key])
    );
  }
  private definedReactive(data: Data, key: string, value: any) {
    const _this = this;
    this.walk(value);
    const dep = new Dep();
    Object.defineProperty(data, key, {
      enumerable: true,
      configurable: true,
      get() {
        if (Dep.target) {
          dep.addSub(Dep.target);
        }
        return value;
      },
      set(new_value: any) {
        if (value === new_value) return;
        value = new_value;
        _this.walk(new_value);
        dep.notify();
      },
    });
  }
}
